package com.bsd.xxyp.rdlock.executor;

import com.bsd.xxyp.rdlock.entity.LockInfo;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;

import java.util.concurrent.TimeUnit;

/**
 * @author ：wangcheng
 * @date 2022/12/12
 **/
@Slf4j
public class RedissonLockExecutor implements LockExecutor<RLock> {

    private RedissonClient redisClient;

    public RedissonLockExecutor(RedissonClient redisClient) {
        this.redisClient = redisClient;
    }


    @Override
    public boolean tryAcquire(LockInfo<RLock> lockInfo) {
        RLock lock = redisClient.getLock(lockInfo.getLockKey());
        lockInfo.setLockClient(lock);
        try {
            return lock.tryLock(lockInfo.getWaitTime(), lockInfo.getLockTimeout(), TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            log.error("rdLock lock error: {}",e.getMessage());
        }
        return false;
    }

    @Override
    public boolean releaseLock(LockInfo<RLock> lockInfo) {
        RLock rLock = lockInfo.getLockClient();
        //这里用来判断当前线程持有锁,（防止锁提前过期,此时锁释放,当前线程不再持有锁,）再去解锁会抛异常
        if (rLock.isHeldByCurrentThread() && lockInfo.isLockSuccess()) {
            try {
//                Boolean unLock = rLock.forceUnlockAsync().get();
//                if (unLock!=null && unLock){
//                    return true;
//                }
                rLock.unlock();
                return true;
            }catch (Exception e){
                log.error("rdLock release lock exception: {}",e.getMessage());
                return false;
            }
        }else {
            log.info("rdLock: currentThread not hold lock so no need releaseLock ,lockKey: {} ",lockInfo.getLockKey());
            return false;
        }
    }
}
